//C语言的TCP多线程服务器
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <pthread.h>

#define SERVER_IP "192.168.10.1"
#define SERVER_PORT 1023
#define BUFFER_SIZE 1024
#define GPIO461_PATH "/sys/class/gpio/gpio461"
#define GPIO462_PATH "/sys/class/gpio/gpio462"

//读取GPIO值函数
int read_gpio(const char *gpio_path) {
    char full_path[256];
    snprintf(full_path, sizeof(full_path), "%s/value", gpio_path);

    int fd = open(full_path, O_RDONLY);
    if (fd < 0) {
        perror("open gpio");
        return -1;
    }

    char value;
    ssize_t bytes_read = read(fd, &value, 1);
    if (bytes_read < 0) {
        perror("read gpio");
        close(fd);
        return -1;
    }
    close(fd);
    // 确保读取到的字符是'0'或'1'，然后转换为整数
    if (value == '0') {
        return 0;
    } else if (value == '1') {
        return 1;
    } else {
        // 处理其他可能的情况
        return -1;
    }
    
}

// 设置GPIO值
void set_gpio(const char *gpio_path, int value) {
    char full_path[256];
    snprintf(full_path, sizeof(full_path), "%s/value", gpio_path);
    
    int fd = open(full_path, O_WRONLY);
    if (fd < 0) {
        perror("open gpio");
        return;
    }
    char buffer;
    int num;
    if (value == 1) {
        num = 49;
        buffer = num;
    } else {
        num = 48;
        buffer = num;
    }
    ssize_t bytes_written = write(fd, &buffer, 1);
    if (bytes_written < 0) {
        perror("write gpio");
    }
    close(fd);
}

// 线程函数：检测GPIO462的值
void* monitor_gpio462(void* arg) {
    int client_socket = *((int*)arg);
    while (1) {
        if (read_gpio(GPIO462_PATH) == 0) {
            const char *message = "Fire in the hole!!!\n";
            send(client_socket, message, strlen(message), 0);
            printf("%s\n", message);
        }
    }
    return NULL;
}

// 线程函数：处理客户端信号
void* handle_client_signals(void* arg) {
    int client_socket = *((int*)arg);
    char buffer[BUFFER_SIZE];
    ssize_t bytes_read;

    while (1) {
        if ((bytes_read = recv(client_socket, buffer, BUFFER_SIZE - 1, 0)) > 0) {
            buffer[bytes_read] = '\0';
            if (strcmp(buffer, "a") == 0) {
                set_gpio(GPIO461_PATH, 1);
            } else if (strcmp(buffer, "b") == 0) {
                set_gpio(GPIO461_PATH, 0);
            } else if (strcmp(buffer, "c") == 0) {
                close(client_socket);
                pthread_exit(NULL);
            }
        } else if (bytes_read < 0) {
            perror("recv");
            pthread_exit(NULL);
        }
    }
    return NULL;
}

void handle_client(int client_socket) {
    pthread_t gpio_thread, signal_thread;
    int *socket_ptr = (int*)malloc(sizeof(int));
    *socket_ptr = client_socket;

    // 创建线程
    if (pthread_create(&gpio_thread, NULL, monitor_gpio462, socket_ptr)!= 0) {
        perror("pthread_create gpio_thread");
        free(socket_ptr);
        close(client_socket);
        return;
    }
    if (pthread_create(&signal_thread, NULL, handle_client_signals, socket_ptr)!= 0) {
        perror("pthread_create signal_thread");
        pthread_cancel(gpio_thread);
        free(socket_ptr);
        close(client_socket);
        return;
    }

    // 等待线程结束
    pthread_join(gpio_thread, NULL);
    pthread_join(signal_thread, NULL);

    free(socket_ptr);
    close(client_socket);
    exit(0);
}

int main() {
    int server_socket, client_socket;
    struct sockaddr_in server_addr, client_addr;
    socklen_t client_addr_len = sizeof(client_addr);

    // 创建套接字
    server_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (server_socket < 0) {
        perror("Socket creation failed");
        return 1;
    }

    // 设置端口复用
    int optval = 1;
    if (setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0) {
        perror("setsockopt");
        close(server_socket);
        return 1;
    }

    // 准备地址结构
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(SERVER_PORT);
    server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);

    // 绑定套接字到地址
    if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
        perror("Bind failed");
        close(server_socket);
        return 1;
    }

    // 监听连接
    if (listen(server_socket, 5) < 0) {
        perror("Listen failed");
        close(server_socket);
        return 1;
    }

    printf("Server is listening on %s:%d...\n", SERVER_IP, SERVER_PORT);

    while (1) {
        // 接受客户端连接
        client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &client_addr_len);
        if (client_socket < 0) {
            perror("Accept failed");
            continue;
        }

        // 创建子进程
        pid_t pid = fork();
        if (pid < 0) {
            perror("fork");
            close(client_socket);
        } else if (pid == 0) {
            // 子进程处理客户端连接
            close(server_socket);  // 子进程关闭监听套接字
            handle_client(client_socket);
        } else {
            // 父进程继续监听
            close(client_socket);  // 父进程关闭客户端套接字
            // 回收子进程资源，避免僵尸进程
            while (waitpid(-1, NULL, WNOHANG) > 0);
        }
    }

    close(server_socket);
    return 0;
}
